using Lzfy_Refund_Service.Models;
using Lzfy_Refund_Service.Repositories;

namespace Lzfy_Refund_Service.Services
{
    public class RefundService : IRefundService
    {
        private readonly IRefundMasterRepository _refundMasterRepository;
        private readonly IRefundAttachRepository _refundAttachRepository;
        private readonly IRefundAcctRepository _refundAcctRepository;

        public RefundService(IRefundMasterRepository refundMasterRepository, IRefundAttachRepository refundAttachRepository, IRefundAcctRepository refundAcctRepository)
        {
            _refundMasterRepository = refundMasterRepository;
            _refundAttachRepository = refundAttachRepository;
            _refundAcctRepository = refundAcctRepository;
        }

        public async Task<RefundResponse?> GetRefundByIdAsync(int id)
        {
            var master = await _refundMasterRepository.GetByIdAsync(id);
            if (master == null) return null;

            return await BuildRefundResponseAsync(master);
        }

        public async Task<RefundResponse?> GetRefundByRelIdAsync(string relId)
        {
            var master = await _refundMasterRepository.GetByRelIdAsync(relId);
            if (master == null) return null;

            return await BuildRefundResponseAsync(master);
        }

        public async Task<IEnumerable<RefundResponse>> GetAllRefundsAsync()
        {
            var masters = await _refundMasterRepository.GetAllAsync();
            var responses = new List<RefundResponse>();

            foreach (var master in masters)
            {
                var response = await BuildRefundResponseAsync(master);
                responses.Add(response);
            }

            return responses;
        }

        public async Task<IEnumerable<RefundResponse>> GetRefundsByPatientIdAsync(string patientId)
        {
            var masters = await _refundMasterRepository.GetByPatientIdAsync(patientId);
            var responses = new List<RefundResponse>();

            foreach (var master in masters)
            {
                var response = await BuildRefundResponseAsync(master);
                responses.Add(response);
            }

            return responses;
        }

        public async Task<IEnumerable<RefundResponse>> GetRefundsByPatientIdAndDateRangeAsync(string patientId, int days)
        {
            var masters = await _refundMasterRepository.GetByPatientIdAndDateRangeAsync(patientId, days);
            var responses = new List<RefundResponse>();

            foreach (var master in masters)
            {
                var response = await BuildRefundResponseAsync(master);
                responses.Add(response);
            }

            return responses;
        }

        public async Task<RefundQueryResponse> GetRefundsWithFilterAsync(RefundQueryRequest request)
        {
            // 如果没有指定日期范围，默认查询30天内的数据
            var startDate = request.StartDate;
            var endDate = request.EndDate;
            
            if (!startDate.HasValue && !endDate.HasValue)
            {
                var defaultDays = request.DefaultDays > 0 ? request.DefaultDays : 30;
                endDate = DateTime.Now.Date.AddDays(1).AddTicks(-1); // 今天结束
                startDate = DateTime.Now.Date.AddDays(-defaultDays); // 默认天数前开始
            }

            var (data, totalCount) = await _refundMasterRepository.GetRefundsWithFilterAsync(
                startDate: startDate,
                endDate: endDate,
                auditStatus: request.AuditStatus,
                patientId: request.PatientId,
                patientName: request.PatientName,
                pageIndex: request.PageIndex,
                pageSize: request.PageSize
            );

            var responseList = new List<RefundResponse>();
            foreach (var master in data)
            {
                var response = await BuildRefundResponseAsync(master);
                responseList.Add(response);
            }

            return new RefundQueryResponse
            {
                Data = responseList,
                TotalCount = totalCount,
                PageIndex = request.PageIndex,
                PageSize = request.PageSize
            };
        }

        public async Task<StatisticsQueryResponse> GetRefundStatisticsAsync(StatisticsQueryRequest request)
        {
            // 使用Repository的高效查询方法
            var (data, totalCount) = await _refundMasterRepository.GetRefundStatisticsAsync(
                startDate: request.StartDate,
                endDate: request.EndDate,
                auditStatus: request.AuditStatus,
                applicantType: request.ApplicantType,
                patientId: request.PatientId,
                patientName: request.PatientName,
                bankCardHolder: request.BankCardHolder,
                pageIndex: request.PageIndex,
                pageSize: request.PageSize
            );

            // 将RefundMaster转换为RefundResponse
            var responseList = new List<RefundResponse>();
            foreach (var master in data)
            {
                var response = await BuildRefundResponseAsync(master);
                responseList.Add(response);
            }

            // 为了计算统计概览，需要获取所有符合条件的数据（不分页）
            var (allFilteredData, _) = await _refundMasterRepository.GetRefundStatisticsAsync(
                startDate: request.StartDate,
                endDate: request.EndDate,
                auditStatus: request.AuditStatus,
                applicantType: request.ApplicantType,
                patientId: request.PatientId,
                patientName: request.PatientName,
                bankCardHolder: request.BankCardHolder,
                pageIndex: 1,
                pageSize: int.MaxValue // 获取所有数据用于统计
            );

            // 将所有数据也转换为RefundResponse用于统计
            var allResponseList = new List<RefundResponse>();
            foreach (var master in allFilteredData)
            {
                var response = await BuildRefundResponseAsync(master);
                allResponseList.Add(response);
            }

            // 计算统计概览
            var summary = new StatisticsSummary
            {
                TotalApplications = allResponseList.Count,
                ApprovedCount = allResponseList.Count(x => x.AuditResult == "1" || x.AuditResult == "通过"),
                RejectedCount = allResponseList.Count(x => x.AuditResult == "2" || x.AuditResult == "拒绝"),
                PendingCount = allResponseList.Count(x => string.IsNullOrEmpty(x.AuditResult) || x.AuditResult == "0" || x.AuditResult == "待审核"),
                TotalRefundAmount = allResponseList.Sum(x => x.RefundAmount ?? 0),
                ApprovedRefundAmount = allResponseList.Where(x => x.AuditResult == "1" || x.AuditResult == "通过").Sum(x => x.RefundAmount ?? 0)
            };

            return new StatisticsQueryResponse
            {
                Data = responseList,
                TotalCount = totalCount,
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                Summary = summary
            };
        }

        public async Task<int> CreateRefundAsync(RefundMasterCreateRequest request)
        {
            // 生成UUID作为关联ID
            var relId = Guid.NewGuid().ToString();

            // 创建主表记录
            var master = new RefundMaster
            {
                PatientId = request.PatientId,
                PatName = request.PatName,
                IdNumber = request.IdNumber,
                PhoneNumber = request.PhoneNumber,
                RefundBankName = request.RefundBankName,
                RefundBankCardNo = request.RefundBankCardNo,
                RefundBankOpenName = request.RefundBankOpenName,
                RefundBankCity = request.RefundBankCity,
                RefundAmount = request.RefundAmount,
                PublicAgentName = request.PublicAgentName,
                PublicAgentPhoneNumber = request.PublicAgentPhoneNumber,
                PublicAgentRelation = request.PublicAgentRelation,
                PublicAgentRelationId = request.PublicAgentRelationId,
                PublicAgentRefundBankName = request.PublicAgentRefundBankName,
                PublicAgentRefundBankCardNo = request.PublicAgentRefundBankCardNo,
                PublicAgentRefundBankOpenName = request.PublicAgentRefundBankOpenName,
                PublicAgentRefundBankCity = request.PublicAgentRefundBankCity,
                RefundTypeName = request.RefundTypeName,
                RefundTypeId = request.RefundTypeId,
                RelId = relId,
                BankCardHolder = request.BankCardHolder,
                AcctId = request.AcctId
            };

            var masterId = await _refundMasterRepository.CreateAsync(master);

            // 创建附件记录
            foreach (var attachRequest in request.Attachments)
            {
                var attach = new RefundAttach
                {
                    AttachName = attachRequest.AttachName,
                    AttachId = attachRequest.AttachId,
                    AttachFiles = null, // 不再使用二进制文件存储
                    RelId = relId,
                    FilePaths = attachRequest.FilePaths,
                    FileId = attachRequest.FileId
                };

                await _refundAttachRepository.CreateAsync(attach);
            }

            return masterId;
        }

        public async Task<bool> UpdateRefundAsync(int id, RefundMasterCreateRequest request)
        {
            var existingMaster = await _refundMasterRepository.GetByIdAsync(id);
            if (existingMaster == null) return false;

            // 更新主表
            existingMaster.PatientId = request.PatientId;
            existingMaster.PatName = request.PatName;
            existingMaster.IdNumber = request.IdNumber;
            existingMaster.PhoneNumber = request.PhoneNumber;
            existingMaster.RefundBankName = request.RefundBankName;
            existingMaster.RefundBankCardNo = request.RefundBankCardNo;
            existingMaster.RefundBankOpenName = request.RefundBankOpenName;
            existingMaster.RefundBankCity = request.RefundBankCity;
            existingMaster.RefundAmount = request.RefundAmount;
            existingMaster.PublicAgentName = request.PublicAgentName;
            existingMaster.PublicAgentPhoneNumber = request.PublicAgentPhoneNumber;
            existingMaster.PublicAgentRelation = request.PublicAgentRelation;
            existingMaster.PublicAgentRelationId = request.PublicAgentRelationId;
            existingMaster.PublicAgentRefundBankName = request.PublicAgentRefundBankName;
            existingMaster.PublicAgentRefundBankCardNo = request.PublicAgentRefundBankCardNo;
            existingMaster.PublicAgentRefundBankOpenName = request.PublicAgentRefundBankOpenName;
            existingMaster.PublicAgentRefundBankCity = request.PublicAgentRefundBankCity;
            existingMaster.RefundTypeName = request.RefundTypeName;
            existingMaster.RefundTypeId = request.RefundTypeId;
            existingMaster.BankCardHolder = request.BankCardHolder;
            existingMaster.AcctId = request.AcctId;

            var masterUpdated = await _refundMasterRepository.UpdateAsync(existingMaster);

            // 删除原有附件
            await _refundAttachRepository.DeleteByRelIdAsync(existingMaster.RelId!);

            // 创建新附件
            foreach (var attachRequest in request.Attachments)
            {
                var attach = new RefundAttach
                {
                    AttachName = attachRequest.AttachName,
                    AttachId = attachRequest.AttachId,
                    AttachFiles = null, // 不再使用二进制文件存储
                    RelId = existingMaster.RelId
                };

                await _refundAttachRepository.CreateAsync(attach);
            }

            return masterUpdated;
        }

        public async Task<bool> DeleteRefundAsync(int id)
        {
            var master = await _refundMasterRepository.GetByIdAsync(id);
            if (master == null) return false;

            // 删除附件
            await _refundAttachRepository.DeleteByRelIdAsync(master.RelId!);

            // 删除主表
            return await _refundMasterRepository.DeleteAsync(id);
        }

        public async Task<RefundResponse?> AuditRefundAsync(int id, RefundMasterUpdateRequest request)
        {
            // 使用并发控制的审核方法
            var success = await _refundMasterRepository.UpdateAuditWithConcurrencyCheckAsync(id, request);
            if (!success)
            {
                // 检查记录是否存在
                var existingRefund = await _refundMasterRepository.GetByIdAsync(id);
                if (existingRefund == null)
                {
                    throw new ArgumentException($"退费申请 {id} 不存在");
                }
                
                // 检查是否已被审核
                if (!string.IsNullOrEmpty(existingRefund.AuditResult) && existingRefund.AuditResult != "0")
                {
                    throw new InvalidOperationException($"退费申请 {id} 已被审核，无法重复审核。当前审核状态：{GetAuditStatusText(existingRefund.AuditResult)}，审核人：{existingRefund.AuditUserName}，审核时间：{existingRefund.AuditDate:yyyy-MM-dd HH:mm:ss}");
                }
                
                throw new InvalidOperationException($"退费申请 {id} 审核失败");
            }
            
            // 返回更新后的数据
            return await GetRefundByIdAsync(id);
        }
        
        private string GetAuditStatusText(string auditResult)
        {
            return auditResult switch
            {
                "1" => "审核通过",
                "2" => "审核拒绝",
                "0" => "待审核",
                _ => "未知状态"
            };
        }

        private async Task<RefundResponse> BuildRefundResponseAsync(RefundMaster master)
        {
            var attachments = await _refundAttachRepository.GetByRelIdAsync(master.RelId!);
            
            var response = new RefundResponse
            {
                Id = master.Id,
                InputDate = master.InputDate,
                PatientId = master.PatientId,
                PatName = master.PatName,
                IdNumber = master.IdNumber,
                PhoneNumber = master.PhoneNumber,
                RefundBankName = master.RefundBankName,
                RefundBankCardNo = master.RefundBankCardNo,
                RefundBankOpenName = master.RefundBankOpenName,
                RefundBankCity = master.RefundBankCity,
                RefundAmount = master.RefundAmount,
                PublicAgentName = master.PublicAgentName,
                PublicAgentPhoneNumber = master.PublicAgentPhoneNumber,
                PublicAgentRelation = master.PublicAgentRelation,
                PublicAgentRelationId = master.PublicAgentRelationId,
                PublicAgentRefundBankName = master.PublicAgentRefundBankName,
                PublicAgentRefundBankCardNo = master.PublicAgentRefundBankCardNo,
                PublicAgentRefundBankOpenName = master.PublicAgentRefundBankOpenName,
                PublicAgentRefundBankCity = master.PublicAgentRefundBankCity,
                AuditUserId = master.AuditUserId,
            AuditUserName = master.AuditUserName,
            AuditResult = master.AuditResult,
                AuditDate = master.AuditDate,
                RefundTypeName = master.RefundTypeName,
                RefundTypeId = master.RefundTypeId,
                AuditComment = master.AuditComment,
                RelId = master.RelId,
                BankCardHolder = master.BankCardHolder,
                RefundBalance = master.RefundBalance,
                RefundBalanceSn = master.RefundBalanceSn,
                AcctId = master.AcctId,
                Attachments = attachments.Select(a => new RefundAttachResponse
                {
                    Id = a.Id,
                    InputDate = a.InputDate,
                    AttachName = a.AttachName,
                    AttachId = a.AttachId,
                    // FilePaths属性在RefundAttachResponse中不存在，需要移除或在模型中添加该属性
                    // 由于 RefundAttachResponse 未定义 FileId 属性，此处移除该字段映射
                    FilePaths = a.FilePaths,
                    FileId = a.FileId,
                    AttachFilePath = null, // 文件路径字段，暂时为空
                    RelId = a.RelId
                }).ToList()
            };

            return response;
        }

        public async Task<PagedResult<RefundResponse>> GetRefundsPagedAsync(int pageNumber, int pageSize, DateTime? startDate, DateTime? endDate, string? auditResult, string? settleStatus = null, string? bankCardHolder = null, string? auditUserName = null)
        {
            var (data, totalCount) = await _refundMasterRepository.GetRefundsPagedAsync(pageNumber, pageSize, startDate, endDate, auditResult, settleStatus, bankCardHolder, auditUserName);
            
            var responseList = new List<RefundResponse>();
            foreach (var master in data)
            {
                var response = await BuildRefundResponseAsync(master);
                responseList.Add(response);
            }

            return new PagedResult<RefundResponse>
            {
                Items = responseList,
                TotalCount = totalCount,
                PageNumber = pageNumber,
                PageSize = pageSize
            };
        }

        public async Task<BatchSettleResponse> BatchSettleAsync(List<int> refundIds, string operatorName, string operatorFullName)
        {
            // 验证所有记录都是审核通过且未结算的
            var refunds = new List<RefundMaster>();
            foreach (var id in refundIds)
            {
                var refund = await _refundMasterRepository.GetByIdAsync(id);
                if (refund == null)
                {
                    throw new ArgumentException($"退费记录 {id} 不存在");
                }
                if (refund.AuditResult != "1")
                {
                    throw new ArgumentException($"退费记录 {id} 未审核通过，无法结算");
                }
                if (!string.IsNullOrEmpty(refund.AcctId))
                {
                    throw new ArgumentException($"退费记录 {id} 已结算，无法重复结算");
                }
                refunds.Add(refund);
            }

            // 生成结算ID
            var acctId = Guid.NewGuid().ToString();
            var totalAmount = refunds.Sum(r => r.RefundBalance ?? 0);
            var settleDate = DateTime.Now;

            // 使用事务和并发控制更新退费记录的结算ID
            var successCount = 0;
            var failedIds = new List<int>();
            
            foreach (var refund in refunds)
            {
                var updated = await _refundMasterRepository.UpdateAcctIdWithConcurrencyCheckAsync(refund.Id, acctId);
                if (updated)
                {
                    successCount++;
                }
                else
                {
                    failedIds.Add(refund.Id);
                }
            }
            
            // 如果有记录更新失败，说明已被其他用户结算
            if (failedIds.Count > 0)
            {
                throw new InvalidOperationException($"以下退费记录已被其他用户结算，无法重复结算：{string.Join(", ", failedIds)}");
            }

            // 创建结算记录
            var refundAcct = new RefundAcct
            {
                AcctId = acctId,
                RefundBalanceSum = totalAmount,
                Username = operatorName,
                FullName = operatorFullName,
                InputDate = settleDate
            };

            // 添加调试日志
            Console.WriteLine($"[DEBUG] BatchSettleAsync - operatorName: {operatorName}, operatorFullName: {operatorFullName}");
            Console.WriteLine($"[DEBUG] RefundAcct object - Username: {refundAcct.Username}, FullName: {refundAcct.FullName}");

            // 创建结算记录
            await _refundAcctRepository.CreateAsync(refundAcct);

            // 重新计算实际结算的金额（基于成功更新的记录）
            var actualTotalAmount = refunds.Take(successCount).Sum(r => r.RefundBalance ?? 0);
            
            return new BatchSettleResponse
            {
                AcctId = acctId,
                TotalAmount = actualTotalAmount,
                SettledCount = successCount,
                SettleDate = settleDate
            };
        }

        public async Task<IEnumerable<RefundResponse>> GetRefundsByAcctIdAsync(string acctId)
        {
            var masters = await _refundMasterRepository.GetByAcctIdAsync(acctId);
            var responses = new List<RefundResponse>();

            foreach (var master in masters)
            {
                var response = await BuildRefundResponseAsync(master);
                responses.Add(response);
            }

            return responses;
        }

        public async Task<bool> UpdateHisRefundStatusAsync(int id, string hisRefundStatus)
        {
            return await _refundMasterRepository.UpdateHisRefundStatusAsync(id, hisRefundStatus);
        }
    }
}